package v1

import (
	"errors"
	"github.com/astaxie/beego/validation"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
	"zhejianglab/gin-apiserver/model"
	"zhejianglab/gin-apiserver/model/request"
)

// AddNewClue create new Clue
// @Produce  json
// @Tags Clue
// @Param AddNewClue body request.ClueInfo true "request.ClueInfo"
// @Success 201 {object} gin.H "{"code":201,"msg":"AddNewClue successfully"}"
// @Failure 409 {object} gin.H "{"code":500,"msg":"AddNewClue: Clue name is exist"}"
// @Failure 500 {object} gin.H "{"code":500,"msg":"AddNewClue: Clue name is invalid"}"
// @Router /api/v1/clue/new [post]
func AddNewClue(c *gin.Context) {
	var err error

	var Clue request.ClueInfo
	err = c.ShouldBindJSON(&Clue)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error()})
		return
	}
	clueInfo := model.ClueInfo{
		UserID:          Clue.UserID,
		Type:            Clue.Type,
		CameraID:        Clue.CameraID,
		JobID:           Clue.JobID,
		FileKey:         Clue.FileKey,
		BeginFrameIndex: Clue.BeginFrameIndex,
		EndFrameIndex:   Clue.EndFrameIndex,
	}
	valid := validation.Validation{}

	// 校验输入参数的有效性
	valid.Required(Clue.UserID, "userID").Message("userID不能为空")
	if valid.HasErrors() {
		err = errors.New("AddNewClue: Clue userID is invalid")
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error(), "data": Clue.UserID})
		return
	}
	if Clue.Type != 0 {
		if Clue.CameraID <= 0 {
			err = errors.New("AddNewClue: Clue cameraID is invalid")
			c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error(), "data": Clue.UserID})
			return
		}
	}

	data, err := model.AddNewClue(&clueInfo)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error()})
		return
	}
	clue, ok := data.(*model.ClueInfo)
	if !ok {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": "AddNewJob failed!"})
		return
	}

	c.JSON(http.StatusCreated, gin.H{"status": http.StatusCreated, "message": "AddNewClue successfully!", "data": clue.ID})
}

// GetClue get Clue info from db
// @Produce  json
// @Tags Clue
// @Param id path int true "ID"
// @Success 200 {object} gin.H "{"code":200,"msg":"GetClue successfully"}"
// @Failure 500 {object} gin.H "{"code":500,"msg":"GetClue failed!"}"
// @Router /api/v1/clue [get]
func GetClue(c *gin.Context) {
	userID := c.Query("user_id")
	if userID != "" {
		data, err := model.GetClueByUserID(userID)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error()})
			return
		}
		c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "message": "GetClueByTaskID successfully!", "data": data})
	} else {
		data, err := model.GetAllClues()
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error()})
			return
		}
		c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "message": "GetClue successfully!", "data": data})
	}

}

// UpdateClue update new Clue
// @Produce  json
// @Tags Clue
// @Param ClueInfo body request.ClueInfo true "request.ClueInfo"
// @Success 201 {object} gin.H "{"code":201,"msg":"UpdateClue successfully"}"
// @Failure 409 {object} gin.H "{"code":500,"msg":"UpdateClue: Clue name is exist"}"
// @Failure 500 {object} gin.H "{"code":500,"msg":"UpdateClue: Clue name is invalid"}"
// @Router /api/v1/clue/{id} [put]
func UpdateClue(c *gin.Context) {
	var err error
	data := make(map[string]interface{})
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error()})
		return
	}
	if !model.ExistClueByID(id) {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": "Clue id is not exists failed!"})
		return
	}

	var Clue request.ClueInfo

	err = c.ShouldBindJSON(&Clue)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": "UpdateClue failed!" + err.Error()})
		return
	}

	if Clue.UserID != 0 {
		data["user_id"] = Clue.UserID
	}
	if Clue.Type != 0 {
		data["type"] = Clue.Type
	}
	if Clue.CameraID != 0 {
		data["camera_id"] = Clue.CameraID
	}
	if Clue.JobID != 0 {
		data["job_id"] = Clue.JobID
	}
	if Clue.FileKey != "" {
		data["file_key"] = Clue.FileKey
	}
	if Clue.BeginFrameIndex != 0 {
		data["begin_frame_index"] = Clue.BeginFrameIndex
	}
	if Clue.EndFrameIndex != 0 {
		data["end_frame_index"] = Clue.EndFrameIndex
	}

	model.UpdateClue(id, data)
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "message": "UpdateClue successfully!", "data": data})
	return

}

// DeleteClue delete case info from db
// @Produce  json
// @Tags Clue
// @Param id path int true "ID"
// @Success 200 {object} gin.H "{"code":200,"msg":"DeleteClue successfully"}"
// @Failure 500 {object} gin.H "{"code":500,"msg":"DeleteClue failed!"}"
// @Failure 500 {object} gin.H "{"code":500,"msg":"id is invalid!"}"
// @Router /api/v1/clue/{id} [delete]
func DeleteClue(c *gin.Context) {
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error()})
		return
	}

	valid := validation.Validation{}
	valid.Min(id, 1, "id").Message("ID必须大于0")

	if !valid.HasErrors() {
		if model.ExistClueByID(id) {
			model.DeleteClue(id)
			c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "message": "DeleteClue successfully!"})
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": "DeleteClue failed!"})
			return
		}
	} else {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": "id is invalid!"})
		return
	}
}
